home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / freeWAIS-sf-1.1 / ir / weight.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-31  |  7.0 KB  |  218 lines

  1. /*                               -*- Mode: C -*- 
  2.  * weight.c -- 
  3.  * ITIID           : $ITI$ $Header $__Header$
  4.  * Author          : Huynh Quoc T. Tung
  5.  * Created On      : Tue May 17 11:45:07 1994
  6.  * Last Modified By: Ulrich Pfeifer
  7.  * Last Modified On: Mon May 30 17:13:10 1994
  8.  * Update Count    : 35
  9.  * Status          : Unknown, Use with caution!
  10.  */
  11.  
  12. /*********************       INTRODUCTION        ************************
  13.  * The documents would be presented by term vectors of the form
  14.  *       D = (t_0,w_d0; t_1,w_d1; ..., t_t,w_dt)
  15.  * where each t_k identifies a content term assigned to some sample 
  16.  * document and w_dk represents the weight of term t_k in Document D
  17.  * (or query Q). Thus, a typical query Q might be formulated as
  18.  *       Q = (q_0,w_q0; q_1,w_q1; ...; q_t,w_qt)
  19.  * where q_k once again reprents a term assigned to query Q.
  20.  * The weights could be allowed to vary continuosly between 0 and 1, the
  21.  * higher weight assignments near 1 being used for the most important terms,
  22.  * whereas lower weights near 0 would characterize the less important terms.
  23.  * Given the vector representation, a query-document similarity value may
  24.  * be obtained by comparing the corresponding vectors, using for example
  25.  * the conventional vector product formula
  26.  *       similarity(Q,D) = sum(w_qk * w_dk), k=1 to t.
  27.  * 
  28.  * Three factors important for term_weighting:
  29.  * 1) term frequency in individual document (recall)
  30.  * 2) inverse document frequency (precision)
  31.  * 3) document length (vector length)
  32.  * 
  33.  * Term frequency component using here:  new_wgt = 0.5 + 0.5 * tf / max_tf
  34.  * augmented normalized term frequency (tf factor normalized by maximum tf
  35.  * in the vector, and further normalized to lie between 0.5 and 1.0).
  36.  *
  37.  * Collection frequency component using here: 1.0
  38.  * no change in weight; use original term frequency component.
  39.  *
  40.  * Normalization component using here: sqrt(sum(new_wgt^2)) = vector length.
  41.  *
  42.  * Thus, document term weight is: w_dk = new_wgt / vector length
  43.  *
  44.  * By query term weighting it is assumpted that tf is equal 1. So that
  45.  * w_qk = 1.
  46.  *
  47.  ****************************************************************************/
  48.  
  49. /*********************   PROCEDURE DESCRIPTION   ************************
  50.  * assign_term_weight_for_doc(max_tf, number_of_elements, bucket_ids_array, db)
  51.  *    long *max_tf;
  52.  *    long *number_of_elements;
  53.  *    long *bucket_ids_array;
  54.  *    database *db;
  55.  *
  56.  * computing weight and assigning it into the buf.
  57.  *
  58.  * write_weight_in_ptr(weight, ptr)
  59.  *    float weight;
  60.  *    char *ptr;
  61.  *
  62.  * assigning weight into the buf
  63.  *
  64.  * float read_weight_from_stream(new_weight_size, stream)
  65.  *    long new_weight_size;
  66.  *    FILE* stream;
  67.  *
  68.  * reading weight from stream by searching. return weight.
  69.  *
  70.  * void save_terms_of_doc(number_of_terms, db)
  71.  *   long *number_of_term;
  72.  *   database *db;
  73.  *
  74.  * save all terms of document before flushing into disk.
  75.  *
  76.  * void add_terms_saved(is_field, number_of_terms, doc_id, db)
  77.  *   boolean is_field;
  78.  *   long *number_of_terms;
  79.  *   long doc_id;
  80.  *   database *db;
  81.  *
  82.  * add all terms saved into hashtable.
  83.  *
  84.  ****************************************************************************/
  85.  
  86. #include "irfiles.h"
  87. #include "cutil.h"
  88. #ifdef NEW_WEIGHT
  89. #include "futil.h"
  90. #include "hash.h"
  91. #include "irhash.h"
  92. #include "weight.h"
  93. #include <math.h>
  94.  
  95. long max_term_frequency = 0;       /* used in irhash.c */
  96. long bucket_ids_doc_array[DEFAULT_NUMBER_OF_BUCKETS + 1]; /* used in hash.c */
  97.  
  98. void write_weight_in_ptr(weight, ptr)
  99.      float weight;
  100.      unsigned char *ptr;
  101. {
  102.   float tmp_weight[1];
  103.  
  104.   tmp_weight[0] = weight;
  105.   memcpy((unsigned char *)ptr, (unsigned char *)tmp_weight,NEW_WEIGHT_SIZE);
  106. }
  107.  
  108. float read_weight_from_stream(new_weight_size, stream)
  109.      long new_weight_size;
  110.      FILE *stream;
  111. {
  112.   float tmp;
  113.   unsigned char *inc;
  114.   int i;
  115.  
  116.   inc = (unsigned char*) &tmp;
  117.   for (i=0; i<new_weight_size; i++) {
  118.     *inc = fgetc(stream);
  119.     inc++;
  120.   }
  121.   return(tmp);
  122. }
  123.  
  124. void assign_term_weight_for_doc(number_of_elements, db)
  125.      long *number_of_elements;
  126.      database *db;
  127. {
  128.   long i;
  129.   long id;
  130.   long tf;
  131.   float new_wgt;
  132.   float doc_len = 0.0;
  133.   hashtable *htable = db->the_word_memory_hashtable;
  134.   
  135.   /* compute document length */
  136.   for(i=0; i< *number_of_elements; i++) {
  137.     id = bucket_ids_doc_array[i];
  138.     tf =  (htable->contents)[id].occurances_in_doc;
  139.     doc_len += (0.5 + (0.5 * tf / max_term_frequency)) * (0.5 + (0.5 * tf / max_term_frequency));
  140.   }
  141.   doc_len = sqrt(doc_len);
  142.   for(i=0; i< *number_of_elements; i++) {
  143.     id = bucket_ids_doc_array[i];
  144.     tf = (htable->contents)[id].occurances_in_doc;
  145.     (htable->contents)[id].occurances_in_doc = 0;
  146.     new_wgt = (0.5 + (0.5 * tf / max_term_frequency)) / doc_len;
  147.     if ((htable->contents)[id].current_memory_ptr == NULL) {
  148.       fprintf(stderr, "panic: assign_term_weight_for_doc current_memory_ptr == NULL\n");
  149.     } else {
  150.       write_weight_in_ptr(new_wgt, 
  151.               (htable->contents)[id].current_memory_ptr - NEW_WEIGHT_SIZE);
  152.     }
  153.   }
  154.   max_term_frequency = 0;
  155.   *number_of_elements = 0;
  156.   memset(bucket_ids_doc_array, 0, DEFAULT_NUMBER_OF_BUCKETS * sizeof(long));
  157. }
  158.  
  159. term_infotable *termtable = NULL;
  160.  
  161. void save_terms_for_doc(number_of_terms, db)
  162.      long *number_of_terms;
  163.      database *db;
  164. {
  165.   int info_size = CHARACTER_POSITION_SIZE;
  166.   int cn_size = CHARACTER_POSITION_SIZE + NEW_WEIGHT_SIZE;
  167.   long i, id, char_pos;
  168.   hashtable *htable = db->the_word_memory_hashtable;
  169.   
  170.   if(*number_of_terms != 0) {
  171.     if(termtable == NULL)
  172.       termtable = (term_infotable *)s_malloc(sizeof(term_infotable) * *number_of_terms);
  173.     if(termtable == NULL)
  174.       panic("Out of memory");
  175.   }
  176.  
  177.   for(i=0; i < *number_of_terms; i++) {
  178.     id = bucket_ids_doc_array[i];
  179.     if((termtable[i].term = (char*)s_malloc(sizeof(char) * (MAX_KEY_SIZE+1))) == NULL)
  180.       panic("Out of memory");
  181.     strncpy(termtable[i].term, (htable->contents)[id].key, MAX_KEY_SIZE);
  182.     termtable[i].char_pos = 
  183.       read_bytes_from_memory(CHARACTER_POSITION_SIZE,
  184.                  (htable->contents)[id].current_memory_ptr - cn_size);
  185.     termtable[i].tf = (htable->contents)[id].occurances_in_doc;
  186.     if((htable->contents)[id].memory_size - WORD_MEMORY_INIT_BLOCK_SIZE == 0)
  187.       (htable->contents)[id].number_of_occurances = STOP_WORD_FLAG;
  188.     else (htable->contents)[id].current_memory_ptr -= WORD_MEMORY_INIT_BLOCK_SIZE;
  189.   }
  190.   *number_of_terms = 0;
  191. }
  192.  
  193. void add_terms_saved(is_field, number_of_terms, doc_id, db)
  194.      boolean is_field;
  195.      long *number_of_terms;
  196.      long doc_id;
  197.      database *db;
  198. {
  199.   long i, id;
  200.   long number_of_elements = *number_of_terms;
  201.   *number_of_terms = 0;
  202.   for(i=0; i < number_of_elements; i++) {
  203.     if(is_field) 
  204.       field_add_word(termtable[i].term, termtable[i].char_pos,0,1,doc_id,0,0,db,false);
  205.     else 
  206.       add_word(termtable[i].term, termtable[i].char_pos,0,1,doc_id,0,0,db,false);
  207.     id = bucket_ids_doc_array[i];
  208.     (db->the_word_memory_hashtable->contents)[id].occurances_in_doc = termtable[i].tf;
  209.     if(termtable[i].term != NULL)
  210.       s_free(termtable[i].term);
  211.   }
  212.   if(termtable != NULL)
  213.     s_free(termtable);
  214. }
  215.  
  216.  
  217. #endif /* NEW_WEIGHT */
  218.